<template>
  <div class="blindBoxForm" v-bind="$attrs">
    <el-form
      :inline="inline"
      :label-width="labelWidth"
      :model="data"
      label-position="right"
      ref="form"
    >
      <el-row>
        <el-col
          v-for="(item, index) of renderList"
          :key="index"
          :span="colLayout ? (item.span ? item.span : 12) : 4"
        >
          <form-item
            :colLayout="colLayout"
            :ref="item.prop"
            :showLabel="showLabel"
            :formHideField="formHideField"
            :value="data[item.prop]"
            :config="item"
            :formData.sync="data"
            :isReadonly="isReadonly"
            @formDataChange="formItemDataChange"
          >
          </form-item>
        </el-col>
        <el-col :span="4">
          <el-form-item v-if="showButton">
            <el-button class="button" type="primary" @click="search"
              >查询</el-button
            >
            <el-button class="button" @click="$emit('recharge')"
              >清空</el-button
            >
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </div>
</template>

<script>
import FormItem from "../form-item";
import Inject from "../../mixin/inject";

export default {
  mixins: [Inject],
  props: {
    //是否隐藏标题
    showLabel: Boolean,

    // 是否使用col布局（类似于element Layout布局）
    colLayout: Boolean,

    //需要隐藏的字段 [String]
    formHideField: Array,

    //表单数据绑定完成时的回调
    formMounted: [Function, String],
    //表单数据绑定前的回调
    formDataBindBefore: [Function, String],
    //表单数据发生变化时回调
    formDataChange: [Function, String],
    labelWidth: {
      type: String,
      default: "",
    },
    inline: {
      type: Boolean,
      default: true,
    },
    isReadonly: {
      type: Boolean,
      default: false,
    },
    formData: {
      type: Object,
      default: () => {},
    },
    formList: {
      type: Array,
      default: () => [],
    },
    showButton: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      renderList: [],
      formListConfig: Object.create(null),
      data: Object.create(null),
    };
  },
  computed: {
    getFormData() {
      return this.data;
    },
  },
  watch: {
    formList: {
      immediate: true,
      deep: true,
      handler(val) {
        this.$set(this, "renderList", val);
      },
    },
    formData: {
      immediate: true,
      deep: true,
      handler(val) {
        if (this.formDataBindBefore) this.formDataBindBeforeFunction(val);
        this.$set(this, "data", val);
      },
    },
  },
  components: {
    FormItem,
  },
  created() {
    this.init();
    this.$set(this, "renderList", this.formList);
  },
  mounted() {
    if (this.formMounted) this.formMountedFunction();
  },
  methods: {
    // 表单dom加载完毕回调
    formMountedFunction() {
      if (this.formMounted.constructor == Function) {
        try {
          this.formMounted(this.data, this.$refs);
        } catch (error) {
          console.error("[formMounted]：" + error);
        }
      } else if (this.formMounted.constructor == String) {
        this.$CD
          ? this.formMounted.call(this.$CD, this.data, this.$refs)
          : console.error(
              "The formMounted method does not find a parent instance"
            );
      }
    },
    // 表单表单数据绑定前回调
    formDataBindBeforeFunction(formData) {
      if (this.formDataBindBefore.constructor == Function) {
        this.formDataBindBefore(formData);
      } else if (this.formDataBindBefore.constructor == String) {
        this.$CD
          ? this.formDataBindBefore.call(this.$CD, formData)
          : console.error(
              "The formDataBindBefore method does not find a parent instance"
            );
      }
    },

    // 表单数据初始化
    init() {
      let formData = this.formData ? this.formData : this.initData();
      if (this.formDataBindBefore) this.formDataBindBeforeFunction(formData);
      this.$set(this, "data", formData);
    },
    // 表单Change事件
    formItemDataChange(prop) {
      this.$emit("formDataChange", this.$refs, this.data);
      if (this.formDataChange && this.formDataChange.constructor == Function) {
        this.formDataChange(prop, this.data, this.$refs);
      } else if (
        this.formDataChange &&
        this.formDataChange.constructor == String
      ) {
        this.$CD
          ? this.formDataChange.call(this.$CD, prop, this.data, this.$refs)
          : console.error(
              "The formDataChange method does not find a parent instance"
            );
      }
    },
    // 重置
    recharge() {
      Object.keys(this.data).forEach((item) => {
        this.$set(this.data, item, null);
      });
    },

    // 表单验证
    validate() {
      let flag;
      this.$refs.form.validate((res) => {
        flag = res;
      });
      return flag;
    },

    // 搜索
    search() {
      this.$emit("search", this.getFormData);
    },

    // 生成表单数据
    initData() {
      let formData = Object.create(null);
      if (this.formList && this.formList.constructor == Array) {
        this.formList.forEach((item) => {
          if (item.type == "daterange" && item.endTime && item.startTime) {
            this.$set(formData, item.endTime, null);
            this.$set(formData, item.startTime, null);
          } else if (item.prop && item.prop.constructor != Object) {
            this.$set(formData, item.prop, null);
          } else if (item.prop.constructor == Object) {
            this.$set(formData, item.prop.value, null);
            this.$set(formData, item.prop.label, null);
          }
        });
      }
      return formData;
    },
  },
};
</script>
<style lang="scss"></style>
